package com.yuanduo_app.widget;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.google.gson.Gson;
import cn.ydxlm.maplib.MapManager;
import cn.ydxlm.maplib.api.LocationListener;
import cn.ydxlm.maplib.entity.LatLon;
import cn.ydxlm.maplib.entity.Location;
import cn.ydxlm.maplib.entity.Marker;
import cn.ydxlm.maplib.widget.MapView;
import com.xujl.fastlib.utils.CollectionsUtils;
import com.xujl.fastlib.utils.JsonUtil;
import com.xujl.fastlib.utils.NumberUtils;
import com.xujl.fastlib.utils.ResUtils;

import com.yuanduo_app.R;
import com.yuanduo_app.bridge.DataModule;
import com.yuanduo_app.consts.RNEvent;
import com.yuanduo_app.manager.RNModuleManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * 地图控件的RN封装
 */
public class MapViewManager extends SimpleViewManager<MapView> implements LocationListener {
    protected static final String TAG = "MapViewManager";

    private static final int ON_CREATE = 1;
    private static final int ON_RESUME = 2;
    private static final int ON_PAUSE = 3;
    private static final int ON_DESTROY = 4;
    private static final int START_LOCATION = 5;//开始定位
    private static final int DRAW_OVERLAY = 6;//绘制覆盖物
    private static final int DRAW_LINE = 7;//绘制线路
    private static final int DRAW_OVERLAY_TOTAL = 8;//绘制统计数字覆盖物
    private static final int SET_CENTER = 9;//设置中心点

    private MapView mMapView;

    @NonNull
    @Override
    public String getName () {
        return "MapView";
    }


    @NonNull
    @Override
    protected MapView createViewInstance (@NonNull ThemedReactContext reactContext) {
        mMapView = new MapView(reactContext);
        mMapView.setZoomLevelListener((level, lat, lon) -> {
            DataModule module = RNModuleManager.getInstance().getModule(DataModule.class);
            if (module != null) {
                Map<String, Object> map = new HashMap<>();
                map.put("zoomLevel", level);
                map.put("latitude", lat);
                map.put("longitude", lon);
                module.sendEvent(RNEvent.MAP_ZOOM_LEVEL, JsonUtil.toJson(map));
            }
        });
        return mMapView;
    }

    @Nullable
    @Override
    public Map<String, Integer> getCommandsMap () {
        Map<String, Integer> map = new HashMap<>();
        map.put("onCreate", ON_CREATE);
        map.put("onResume", ON_RESUME);
        map.put("onPause", ON_PAUSE);
        map.put("onDestroy", ON_DESTROY);
        map.put("startLocation", START_LOCATION);
        map.put("drawOverlay", DRAW_OVERLAY);
        map.put("drawLine", DRAW_LINE);
        map.put("drawOverlayTotal", DRAW_OVERLAY_TOTAL);
        map.put("setCenter", SET_CENTER);
        return map;
    }

    @ReactProp(name = "locationIcon")
    public void locationIcon (MapView mapView, String locationIcon) {
        mapView.setLocationIcon(ResUtils.getDrawable(locationIcon));
    }

    @Override
    public void receiveCommand (@NonNull MapView root, int commandId, @Nullable ReadableArray args) {
        super.receiveCommand(root, commandId, args);
        Log.i(TAG, "receiveCommand:" + commandId);
        switch (commandId) {
            case ON_CREATE:
                MapManager.getInstance().addLocationListener(this);
                root.onCreate(null);
                break;
            case ON_RESUME:
                root.onResume();
                break;
            case ON_PAUSE:
                root.onPause();
                break;
            case ON_DESTROY:
                root.onDestroy();
                break;
            case START_LOCATION:
                MapManager.getInstance().startLocation();
                break;
            case DRAW_OVERLAY:
                if (args == null) {
                    return;
                }
                final ArrayList<Object> objects = args.toArrayList();
                Map<String, String> iconMap = (Map<String, String>) objects.get(0);
                Map<String, List<Map<String, Double>>> markerMapList = (Map<String, List<Map<String, Double>>>) objects.get(1);
                final int icon = ResUtils.getDrawable(iconMap.get("icon"));
                List<Marker> markerList = new ArrayList<>();
                for (Map<String, Double> map : markerMapList.get("list")) {
                    markerList.add(new Marker(map.get("lat"), map.get("lon"), icon));
                }
                if (CollectionsUtils.isEmpty(markerList)) {
                    return;
                }
                mMapView.addMarker(markerList, icon, icon);
                break;
            case DRAW_OVERLAY_TOTAL:
                if (args == null) {
                    return;
                }
                final ArrayList<Object> objects2 = args.toArrayList();
                Map<String, List<Map<String, Double>>> markerMapList2 = (Map<String, List<Map<String, Double>>>) objects2.get(0);
                List<Marker> markerList2 = new ArrayList<>();
                for (Map<String, Double> map : markerMapList2.get("list")) {
                    markerList2.add(new Marker(map.get("lat"), map.get("lon"), R.drawable.default_img_icon,
                            NumberUtils.intOf(map.get("num") + "") + ""));
                }
                if (CollectionsUtils.isEmpty(markerList2)) {
                    return;
                }
                mMapView.addInfoWindow(markerList2, index -> {
                    final View inflate = LayoutInflater.from(mMapView.getContext()).inflate(R.layout.item_map_info_window, null);
                    TextView tv = inflate.findViewById(R.id.tv_num);
                    tv.setText(markerList2.get(index).getData());
                    return inflate;
                });
                break;
            case DRAW_LINE:
                if (args == null) {
                    return;
                }
                final ArrayList<Object> params = args.toArrayList();
                Map<String, List<Map<String, Double>>> lineListMap = (Map<String, List<Map<String, Double>>>) params.get(0);
                List<LatLon> lineList = new ArrayList<>();
                for (Map<String, Double> map : lineListMap.get("list")) {
                    lineList.add(new LatLon(map.get("lat"), map.get("lon")));
                }
                if (CollectionsUtils.isEmpty(lineList)) {
                    return;
                }
                mMapView.drawLine(lineList, 25f, 0XFF57A5FF);
                break;
            case SET_CENTER:
                if (args == null) {
                    return;
                }
                final ArrayList<Object> paramsCenter = args.toArrayList();
                Map<String, Double> lineListMapCenter = (Map<String, Double>) paramsCenter.get(0);
                mMapView.setCenterPoint(lineListMapCenter.get("lat"), lineListMapCenter.get("lon"));
                break;
            default:
                break;

        }
    }


    @Override
    public void onReceiveLocation (Location location) {
        mMapView.setCenterPoint(location);
        DataModule module = RNModuleManager.getInstance().getModule(DataModule.class);
        if (module != null) {
            module.sendEvent(RNEvent.LOCATION_RESULT, new Gson().toJson(location));
        }
    }
}
